package com.tina.common;

import com.tina.entity.Award;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Tina
 * @version 1.0
 * @since 2021/11/2 17:46
 **/
public class LotteryUtil {
    /**
     * 抽奖，获取中奖奖品
     *
     * @param awardList 奖品及中奖概率列表
     * @return 中奖商品
     */
    public static Award lottery(List<Award> awardList) throws Exception {

        //奖品总数
        int size = awardList.size();

        //计算总概率
        double sumProbability = 0d;
        for (Award award : awardList) {
            sumProbability += award.getProbability();
        }

        //计算每个奖品的概率区间
        //例如奖品A概率区间0-0.1 奖品B概率区间 0.1-0.5 奖品C概率区间0.5-1
        //每个奖品的中奖率越大，所占的概率区间就越大
        List<Double> sortAwardProbabilityList = new ArrayList<Double>(size);
        Double tempSumProbability = 0d;
        for (Award award : awardList) {
            tempSumProbability += award.getProbability();
            sortAwardProbabilityList.add(tempSumProbability / sumProbability);
        }

        //产生0-1之间的随机数
        //随机数在哪个概率区间内，则是哪个奖品
        double randomDouble = Math.random();
        //加入到概率区间中，排序后，返回的下标则是awardList中中奖的下标
        sortAwardProbabilityList.add(randomDouble);
        Collections.sort(sortAwardProbabilityList);
        int lotteryIndex = sortAwardProbabilityList.indexOf(randomDouble);
        return awardList.get(lotteryIndex);
    }

    public static void main(String[] args) throws Exception {
        List<Award> awardList = new ArrayList<Award>();
        awardList.add(new Award(1, "10个积分", 0.35d, 0));
        awardList.add(new Award(2, "33个积分", 0.25d, 0));
        awardList.add(new Award(3, "5元红包", 0.002d, 0));
        awardList.add(new Award(4, "20元话费", 0.003d, 0));
        awardList.add(new Award(5, "100元购物卡", 0.0005d, 0));
        awardList.add(new Award(6, "未中奖", 1.1d, 0));

        List<Award> list = new ArrayList<>();

        for (int i = 0; i < 100000; i++) {
            Award award = lottery(awardList);
            list.add(award);
        }
        List<Award> list2 = new ArrayList<>();
        Map<Award, Long> collect = list.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
        for (Map.Entry<Award, Long> entry : collect.entrySet()) {
            Award award = entry.getKey();
            award.setAppea(Math.toIntExact(entry.getValue()));
            list2.add(award);
        }
        for (Award award : list2) {
            System.out.println(award);
        }
    }
}
